import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:light_compressor_ohos/compression_result.dart';
import 'package:light_compressor_ohos/light_compressor_ohos.dart';
import 'package:light_compressor_ohos/light_compressor_ohos_method_channel.dart';
import 'package:light_compressor_ohos_example/utils/file_utils.dart';

void main() {
  runApp(MyApp());
}

/// A widget that uses LightCompressor library to compress videos
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late String _desFile;
  String? _displayedFile;
  late int _duration;
  String? _failureMessage;
  String? _filePath;
  bool _isVideoCompressed = false;
  bool _isCompressing = false;

  final LightCompressorOhos _lightCompressor = LightCompressorOhos();

  @override
  Widget build(BuildContext context) => MaterialApp(
        theme: ThemeData(
          primaryColor: const Color(0xFF344772),
          primaryColorDark: const Color(0xFF002046),
        ),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('Compressor Sample'),
            actions: <Widget>[
              TextButton(
                child: const Text(
                  'Cancel',
                  style: TextStyle(color: Colors.white, fontSize: 18),
                ),
                onPressed: () => _lightCompressor.cancelCompression(),
              )
            ],
          ),
          body: Container(
            margin: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                if (_filePath != null)
                  Text(
                    'Original path: $_filePath',
                    style: const TextStyle(fontSize: 16),
                  ),
                if (_filePath != null)
                  FutureBuilder(
                    builder: (context, AsyncSnapshot<String> snap) {
                      return Text(
                        'Original size: ${snap.data}',
                        style: const TextStyle(fontSize: 16),
                      );
                    },
                    future: _getVideoSize(filePath: _filePath!),
                  ),
                const SizedBox(height: 8),
                if (_isVideoCompressed)
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        'path after compression: $_desFile',
                        style: const TextStyle(fontSize: 16),
                      ),
                      FutureBuilder(
                        builder: (context, AsyncSnapshot<String> snap) {
                          return Text(
                            'Size after compression: ${snap.data}',
                            style: const TextStyle(fontSize: 16),
                          );
                        },
                        future: _getVideoSize(filePath: _desFile),
                      ),
                      const SizedBox(height: 8),
                      Text(
                        'Duration: $_duration seconds',
                        style: const TextStyle(fontSize: 16, color: Colors.red),
                      ),
                    ],
                  ),
                const SizedBox(height: 16),
                Visibility(
                  visible: !_isVideoCompressed,
                  child: StreamBuilder<double>(
                    stream: _lightCompressor.getUpdateStream(),
                    builder: (BuildContext context,
                        AsyncSnapshot<dynamic> snapshot) {
                      if (snapshot.data != null && snapshot.data > 0) {
                        return Column(
                          children: <Widget>[
                            LinearProgressIndicator(
                              minHeight: 8,
                              value: snapshot.data / 100,
                            ),
                            const SizedBox(height: 8),
                            Text(
                              '${snapshot.data.toStringAsFixed(0)}%',
                              style: const TextStyle(fontSize: 20),
                            )
                          ],
                        );
                      }
                      return const SizedBox.shrink();
                    },
                  ),
                ),
                const SizedBox(height: 24),
                Text(
                  _failureMessage ?? '',
                ),
                if (_isCompressing)
                  const Text(
                    '视频压缩中...',
                    style: TextStyle(color: Colors.red),
                  )
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton.extended(
            onPressed: () => _pickVideo(),
            label: const Text('Pick Video'),
            icon: const Icon(Icons.video_library),
            backgroundColor: const Color(0xFFA52A2A),
          ),
        ),
      );

  // Pick a video form device's storage
  Future<void> _pickVideo() async {
    if (_isCompressing) {
      return;
    }
    _isCompressing = true;
    _isVideoCompressed = false;

    String? file = await _lightCompressor.selectVideo();

    if (file == '') {
      _isCompressing = false;
      return;
    }

    _filePath = file;

    setState(() {
      _failureMessage = null;
    });

    final Stopwatch stopwatch = Stopwatch()..start();
    final Result response = await _lightCompressor.startCompression(
      path: _filePath!,
      videoQuality: VideoQuality.medium,
    );

    stopwatch.stop();
    final Duration duration =
        Duration(milliseconds: stopwatch.elapsedMilliseconds);
    _duration = duration.inSeconds;

    if (response is OnSuccess) {
      setState(() {
        _desFile = response.destinationPath;
        _displayedFile = _desFile;
        _isVideoCompressed = true;
      });
    } else if (response is OnFailure) {
      setState(() {
        _failureMessage = response.message;
      });
    } else if (response is OnCancelled) {
      print(response.isCancelled);
    }
    _isCompressing = false;
  }

  Future<String> _getVideoSize({required String filePath}) async {
    double size = await _lightCompressor.getFileSize(filePath);
    return formatBytes(size.toInt(), 2);
  }
}
